﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using ScFramework.Utilities;
using ScFramework.Core;
using System;
using System.Reflection;
using System.IO;


public class SCompVExTool : Editor
{
        static readonly string path = "Assets/Scripts/SCompVExTools";
    [UnityEditor.Callbacks.DidReloadScripts(0)]
    static void ProduceExtraClass()
    {
           FileExtensions.DeleteAllFile(path);
           var comps= TypeUtilities.GetTypes(typeof(SComponent));
            string baseText = "using System;\nusing UnityEngine;\npublic class ";
        foreach (var s in comps)
        {
            var name = s.FullName;
            var type = s;
            var text = baseText + name + "VEx:IVEx\n{\n";
            text += "public void SetData(ComponentData d){Debug.Assert(TargetType.IsAssignableFrom(d.ComponentType));_data=new WeakReference<ComponentData>(d);}\n";
        //    BindingFlags flags = (System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance|BindingFlags.DeclaredOnly);
          text += "public " + name + "VEx(ComponentData d){SetData(d);}\n";
            text += "public " + name + "VEx(){}\n";
            text += "WeakReference<ComponentData> _data;\n";
          /*  WeakReference<GameObject> tp;
            if(tp.TryGetTarget(out GameObject gameObject))
            {
                new NullReferenceException("弱引用未找到");
            }*/
            text += "public UInt32 CompIdentity{get{if(_data.TryGetTarget(out ComponentData data))return data.CompIdentity;" +
                "else throw new NullReferenceException(\"弱引用未找到\");}}\n";
            text += $"public  Type TargetType=>typeof({name});\n";
            text+="public ComponentData Data{get{if(_data.TryGetTarget(out ComponentData data))return data;\n" +
                "else throw new NullReferenceException(\"弱引用未找到\");}}\n";

            SComponent.TravelSyncValue(s, (FieldInfo v, ushort cnt) =>
             {
                 if (v.GetCustomAttribute<PureValueAtrribute>() != null)
                 {
                     var vtype = v.FieldType.FullName;
                     if (v.FieldType.IsGenericType)
                     {
                         vtype = v.FieldType.FullName.Split('`')[0] + "<";
                         var args = v.FieldType.GetGenericArguments();
                         for (int x = 0; x < args.Length; x++)
                         {

                             vtype += args[x].FullName;
                             if (x != args.Length - 1) vtype += ",";
                         }

                         vtype += ">";
                     }


                     text += $"public {vtype} {v.Name} {{get{{if(_data.TryGetTarget(out ComponentData data))return data.GetValue<{vtype}>({cnt});else throw new NullReferenceException(\"弱引用未找到\");}}\nset{{if(_data.TryGetTarget(out ComponentData data))data.SetValue<{vtype}>({cnt},value,true);else throw new NullReferenceException(\"弱引用未找到\");}}}}\n";
                     text += $"public static ushort {v.Name}Id{{get=>(ushort){cnt};}}\n";
                 }
             }, (PropertyInfo v, ushort cnt) =>
             {
                 if (v.GetCustomAttribute<DynamicValueAtrribute>() != null)
                 {
                     var vtype = v.PropertyType.FullName;
                     if (v.PropertyType.IsGenericType)
                     {
                         vtype = v.PropertyType.FullName.Split('`')[0] + "<";
                         var args = v.PropertyType.GetGenericArguments()[0].GetGenericArguments();
                         for (int x = 0; x < args.Length; x++)
                         {

                             vtype += args[x].FullName;
                             if (x != args.Length - 1) vtype += ",";
                         }

                         vtype += ">";
                     }


                     text += $"public {vtype} {v.Name} {{get{{if(_data.TryGetTarget(out ComponentData data))return data.GetValue<{vtype}>({cnt});else throw new NullReferenceException(\"弱引用未找到\");}}\nset{{if(_data.TryGetTarget(out ComponentData data))data.SetValue<{vtype}>({cnt},value,true);else throw new NullReferenceException(\"弱引用未找到\");}}}}\n";
                     text += $"public static ushort {v.Name}Id{{get=>(ushort){cnt};}}\n";
                 }
             });
            

            text += "\n}\n";
       //     text += $"public partial class {name}{{public static {name}VEx ToVEx(ComponentData c){{return new {name}VEx(c);}}}}\n";

            File.WriteAllText(path+"/"+name+"VEx.cs", text);

        }
    }


}

